package com.tms.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tms.admin.checkUtil.DataCheck;
import com.tms.admin.entity.TmsDriver;
import com.tms.admin.entity.TmsLogistics;
import com.tms.admin.entity.enums.DriverStatusEnum;
import com.tms.admin.entity.enums.LogisticStatusEnum;
import com.tms.admin.entity.vo.DriverQueryVO;
import com.tms.admin.handler.TMSException;
import com.tms.admin.service.TmsDriverService;
import com.tms.admin.mapper.TmsDriverMapper;
import com.tms.admin.service.TmsLogisticsService;
import com.tms.common.entity.ResultCode;
import io.swagger.annotations.ApiOperation;
import io.swagger.models.auth.In;
import kotlin.jvm.internal.Lambda;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

/**
* @author lihao
* @description 针对表【tms_driver】的数据库操作Service实现
* @createDate 2022-09-06 20:05:52
*/
@Service
public class TmsDriverServiceImpl extends ServiceImpl<TmsDriverMapper, TmsDriver>
    implements TmsDriverService{

    @Autowired
    private TmsLogisticsService logisticsService;

    /**
     * 分页+模糊查询司机信息
     * @param driverQueryVO 查询条件
     * @return
     */
    @Override
    public Map<String, Object> getPageByCondition(DriverQueryVO driverQueryVO) {
        /**
         * Step 1. 根据 VO 类, 取出里面所有的查询条件
         *
         * Step 2. 根据查询条件来封装 Wrapper
         *
         * Step 3. 执行分页查询, 获取到 Page 对象
         *
         * Step 4. 将 Page 对象 封装到 Map
         */
        // Step 1: 取出查询条件——司机姓名、联系方式、驾驶车牌号、状态名称、当前页数、每一页最大记录数
        String name = driverQueryVO.getName();
        String phone = driverQueryVO.getPhone();
        String truckNum = driverQueryVO.getTruckNum();
        String state = driverQueryVO.getState();
        if (name == null)
            name = "";
        if (phone == null)
            phone = "";
        if (truckNum == null)
            truckNum = "";
        if (state == null)
            state = "";
        Integer pageNum = driverQueryVO.getPageNum();
        Integer pageSize = driverQueryVO.getPageSize();
        // Step 2：将查询条件封装进 Wrapper
        LambdaQueryWrapper<TmsDriver> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(TmsDriver::getName,name)
                    .like(TmsDriver::getPhone,phone)
                    .like(TmsDriver::getTruckNum,truckNum)
                    .like(TmsDriver::getState,state);
        // Step3 分页查询
        // 创建分页对象——page,初始化分页大小和页数
        if (pageNum == null){
            pageNum = 1;
        }
        if (pageSize == null){
            pageSize = 5;
        }
        Page<TmsDriver> driverPage = new Page<>(pageNum,pageSize);
        baseMapper.selectPage(driverPage,queryWrapper);
        // Step4 将page对象封装到一个 map
        Map<String,Object> pageInfoMap = new HashMap<>();
        pageInfoMap.put("driverList",driverPage.getRecords());
        pageInfoMap.put("pageNum",driverPage.getCurrent());
        pageInfoMap.put("pageSize",driverPage.getSize());
        pageInfoMap.put("total",driverPage.getTotal());
        pageInfoMap.put("hasNext",driverPage.hasNext());
        pageInfoMap.put("hasPrevious",driverPage.hasPrevious());
        return pageInfoMap;
    }

    /**
     * 新增司机记录
     * @param driver
     */
    @Override
    public void addDriver(TmsDriver driver) {
        /**
         * Step 1. 根据 driver 获取 name, gender, phone, truck_num, state, location
         *
         * Step 2. 判断 输入的数据是否为空 若为空 则抛出异常1
         *
         * Step 3. 判断 phone 是否符合11位数字的规范, 不符合则抛出异常2
         *
         * Step 4. 初始化 司机状态为 UNEMPLOYED
         *
         * Step 5. 调用 DAO层接口，将司机添加到 tms_driver表
         */
        // Step 1 初始化司机状态——UNEMPLOYED
        String state = DriverStatusEnum.UNEMPLOYED.name();
        driver.setState(state);
        // Step 2 非空判断
        if (DataCheck.isNullToDriver(driver)){
            throw new TMSException(ResultCode.ERROR,"不允许存在空值");
        }
        // Step 3 电话号码规范性检验
        if (DataCheck.isErrorToPhone(driver.getPhone())){
            throw new TMSException(ResultCode.ERROR,"电话号码格式错误");
        }
        LambdaQueryWrapper<TmsDriver> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.eq(TmsDriver::getTruckNum,driver.getTruckNum());
        if (baseMapper.selectOne(queryWrapper) != null){
            throw new TMSException(ResultCode.ERROR,"车牌号已存在");
        }
        // Step 4 写入数据库
        baseMapper.insert(driver);

    }

    /**
     * 删除司机
     * @param driversIds
     */
    @Override
    public void removeDriversById(List<Integer> driversIds) {
        /**
         * Step 1. 判断 入参 driversIds 是否为空, 为空则抛异常
         *
         * Step 2. 循环遍历 driversIds, 调用 DAO 层的删除方法
         *
         */
        // Step 1
        if (driversIds == null || driversIds.isEmpty()){
            throw new TMSException(ResultCode.FAIL,"未发现需要删除的记录");
        }
        // Step 2 逐个删除记录
        for (Integer dID:driversIds) {
            // 判断司机是否担任物流数据的运输，如果有则不允许删除
            LambdaQueryWrapper<TmsLogistics> logisticWrapper = new LambdaQueryWrapper();
            logisticWrapper.eq(TmsLogistics::getDriverId,dID);
            // 物流表中查询出所有该司机运输的物流记录
            List<TmsLogistics> logisticsList = logisticsService.getBaseMapper().selectList(logisticWrapper);
            if (!logisticsList.isEmpty()){
                for (TmsLogistics logistic :
                        logisticsList) {
                    if (!LogisticStatusEnum.ARRIVED.name().equals(logistic.getStatus())){
                        throw new TMSException(ResultCode.ERROR,"该司机手里有快递派送，如要删除该司机信息，请先找到代替他的司机");
                    }
                }
            }
            // 删除物流表中有该司机的记录
            logisticsService.getBaseMapper().delete(logisticWrapper);
            baseMapper.deleteById(dID);
        }

    }

    /**
     * 修改司机信息
     * @param driver
     */
    @Override
    public void modifyDriverById(TmsDriver driver) {
        /**
         * Step 1. 根据 driver id 判断该司机是否存在，不存在则抛出异常
         *
         * Step 2. 根据 driver 获取 phone，并校验号码格式
         *
         * Step 3. 调用 DAO层方法, 根据 driver 的 id 修改非空的信息
         */
        // Step 1 判断数据库中是否存在该条记录
        Integer dId = driver.getId();
        if (dId == null || baseMapper.selectById(dId) == null){
            throw  new TMSException(ResultCode.ERROR,"不存在该用户,无法修改");
        }
        // Step 1 其他字段的空值检验
        if (DataCheck.isNullToDriver(driver)){
            throw new TMSException(ResultCode.ERROR,"不允许存在空值");
        }
        // Step 2
        String phone = driver.getPhone();
        if (StringUtils.isEmpty(phone) || DataCheck.isErrorToPhone(phone)){
            throw new TMSException(ResultCode.ERROR,"号码格式错误");
        }
        // 验证修改后的车牌号是否与数据库重复
        LambdaQueryWrapper<TmsDriver> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.eq(TmsDriver::getTruckNum,driver.getTruckNum());
        TmsDriver tmsDriver = baseMapper.selectById(driver.getId());
        if (!tmsDriver.getTruckNum().equals(driver.getTruckNum()) && baseMapper.selectOne(queryWrapper) != null){
            throw new TMSException(ResultCode.ERROR,"车牌号已存在");
        }
        // Step 3
        baseMapper.updateById(driver);

    }
}




